package cn.skyquant.quant4j.jforex.strategy.gaia;

import cn.skyquant.quant4j.api.account.AccountType;
import cn.skyquant.quant4j.api.dto.ResultDTO;
import cn.skyquant.quant4j.api.enums.BorkerType;
import cn.skyquant.quant4j.api.order.AccountOrderHisDTO;
import cn.skyquant.quant4j.api.order.OrderService;
import cn.skyquant.quant4j.api.order.OrderServiceProxy;
import cn.skyquant.quant4j.jforex.sdk.strategy2.QuantStrategy;
import cn.skyquant.quant4j.sdk.util.time.CalendarUtils;
import com.dukascopy.api.*;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 盖亚
 * 监控策略
 * @author harley-dog
 */
@Library("quant4j-api.jar;quant4j-sdk.jar;quant4j-jforex-sdk.jar;freemarker-2.3.28.jar;httpclient-4.5.6.jar;httpcore-4.4.10.jar;fastjson-1.2.49.jar;commons-codec-1.11.jar")
public class Gaia extends QuantStrategy {
    OrderService orderService;

    @Override
    protected String getVersion() {
        return "1.0";
    }

    @Override
    protected String getName() {
        return "Gaia";
    }

    private long last_record_time = 0;

    Set<Instrument> instrumentSet = new HashSet<>();

    @Override
    public boolean onStartEx() {
        out("%s","%s",context.getFilesDir());
        orderService = new OrderServiceProxy(account.getAccountId(),BorkerType.DUKASCOPY);
        instrumentSet.add(Instrument.EURUSD);
//        instrumentSet.add(Instrument.GBPUSD);
//        instrumentSet.add(Instrument.USDCAD);
//        instrumentSet.add(Instrument.USDJPY);
//        instrumentSet.add(Instrument.GBPJPY);
//        instrumentSet.add(Instrument.EURJPY);
//        instrumentSet.add(Instrument.EURCHF);
        if (accountType == AccountType.DEMO.name() || accountType == AccountType.LIVE.name()) {
            instrumentSet.add(Instrument.XAUUSD);
        }
        context.setSubscribedInstruments(instrumentSet);
        loadOrderHistory();
        return true;
    }

    @Override
    public void onAccountEx(IAccount account) {
        long time = context.getTime();
        if (time > last_record_time + period.getInterval()) {
            last_record_time = time;
            try {
                updateAccountInfo(account);
            } catch (Exception e) {
                console.getErr().println(e.getMessage());
            }
        }
    }

    @Override
    protected void onStopEx() {
    }


    @Override
    public void onTickEx(Instrument instrument, ITick tick){}

    @Override
    public void onBarEx(Instrument instrument, Period period, IBar askBar, IBar bidBar) {}

    @Override
    public void onMessageEx(IMessage message){

        if(message.getOrder()==null){
            return;
        }
        if(message.getType() != IMessage.Type.ORDER_CLOSE_OK){
            return;
        }
        IOrder order = message.getOrder();
        if(order.getProfitLossInAccountCurrency()==0){
            return;
        }
        String accountId = account.getAccountId();
        saveOrder(order,accountId);
    }


    public void loadOrderHistory(){
        String accountId = account.getAccountId();
        long contextTime = context.getTime();
        for(Instrument instrument:instrumentSet){
            ResultDTO<Long> resultDTO = orderService.getMaxDate(accountId,BorkerType.DUKASCOPY,instrument.name());
            out("%s .his from %s to %s","查到%s的从[%s]到[%s]的历史订单",instrument.name(),CalendarUtils.formatGMTStandard(resultDTO.data), CalendarUtils.formatGMTStandard(contextTime));

            if(resultDTO!=null && resultDTO.okData()){
                long from = resultDTO.data.longValue();
                try {
                    List<IOrder> orderList = history.getOrdersHistory(instrument,from,contextTime);
                    orderList.stream()
                            .filter(x->x.getState()== IOrder.State.CLOSED && x.getProfitLossInAccountCurrency()!=0)
                            .forEach(order->saveOrder(order,accountId));
                } catch (JFException e) {
                    err("%s,getOrdersHistory error:%s,%s",instrument.name(), CalendarUtils.formatGMTStandard(from),CalendarUtils.formatGMTStandard(contextTime));
                }
            }
        }
    }

    private void saveOrder(IOrder order,String accountId){
        AccountOrderHisDTO accountOrderHisDTO = new AccountOrderHisDTO();
        accountOrderHisDTO.id = order.getId();
        accountOrderHisDTO.symbol = order.getInstrument().name();
        accountOrderHisDTO.label = order.getLabel();
        accountOrderHisDTO.accountId = accountId;
        accountOrderHisDTO.amount = order.getAmount();
        accountOrderHisDTO.command = order.getOrderCommand().name();
        accountOrderHisDTO.comment = order.getComment();
        accountOrderHisDTO.openPrice = order.getOpenPrice();
        accountOrderHisDTO.closePrice = order.getClosePrice();
        accountOrderHisDTO.sl = order.getStopLossPrice();
        accountOrderHisDTO.tp = order.getTakeProfitPrice();
        accountOrderHisDTO.creationTime = order.getCreationTime();
        accountOrderHisDTO.fillTime = order.getFillTime();
        accountOrderHisDTO.closeTime = order.getCloseTime();
        accountOrderHisDTO.commission = order.getCommission();
        accountOrderHisDTO.profit = order.getProfitLossInAccountCurrency();
        accountOrderHisDTO.borkerType = BorkerType.DUKASCOPY;
        ResultDTO<Void> resultDTO = orderService.insert(accountOrderHisDTO);
        out("saveOrder: %s, %s %s %s",order.getLabel(),CalendarUtils.formatGMTStandard(order.getCloseTime()),order.getInstrument().name(),order.getProfitLossInUSD());
//        if(resultDTO.okData()){
//            out("saveOrder: %s, %s %s %s"+order.getLabel(),CalendarUtils.formatGMTStandard(order.getCloseTime()),order.getInstrument().name(),order.getProfitLossInUSD());
//        }
    }
}
